"""
此模块用于测试 HX711 称重模块功能。程序会持续读取 HX711 模块的数据，
计算并显示物体的重量，包含去皮重功能。
"""
from gpiozero import DigitalInputDevice, DigitalOutputDevice
import time

# 定义 HX711 传感器的引脚
DOUT_PIN = 5
PD_SCK_PIN = 6

# 使用 gpiozero 初始化引脚
dout = DigitalInputDevice(DOUT_PIN)
pd_sck = DigitalOutputDevice(PD_SCK_PIN)

# 校准参数
pi_weight = 0  # 皮重
# 根据实际重量 66g 和测量重量 94g 计算新的修正系数
new_xishu = 31263 * 66 / 94  
hx711_xishu = new_xishu

def read_hx711():
    """
    读取 HX711 模块的数据。

    :return: 读取到的 24 位有符号整数数据
    """
    # 等待 DOUT 引脚变为低电平，表示数据准备好
    while dout.is_active:
        pass

    value = 0
    for _ in range(24):
        pd_sck.on()
        value = (value << 1) | dout.value
        pd_sck.off()

    # 第 25 个脉冲用于设置增益
    pd_sck.on()
    pd_sck.off()

    # 将 24 位的二进制值转换为有符号整数
    if value & 0x800000:
        value |= ~0xFFFFFF

    return value

def get_tare():
    """
    校准皮重。
    """
    global pi_weight
    # 读取一次数据作为皮重
    hx711_dat = read_hx711()
    pi_weight = hx711_dat * 0.01

def get_weight():
    """
    获取物体的重量。

    :return: 物体的重量，单位为克
    """
    global pi_weight
    hx711_data = read_hx711()
    get = hx711_data * 0.01
    if get > pi_weight:
        weight = (get - pi_weight) * 0.00001 * hx711_xishu
    else:
        if (pi_weight * 0.00001 * hx711_xishu - get * 0.00001 * hx711_xishu) >= 5:
            pass
        weight = 0
    return weight

try:
    print("开始校准皮重，请确保传感器上没有放置任何物体。")
    time.sleep(2)
    get_tare()
    print(f"皮重校准完成，皮重为: {pi_weight}")

    print("开始读取重量，按 Ctrl+C 退出...")
    while True:
        weight = get_weight()
        print(f"当前重量: {weight:.2f} 克")
        time.sleep(0.5)  # 每隔 0.5 秒读取一次重量

except KeyboardInterrupt:
    print("程序终止")
finally:
    # 关闭 HX711 引脚
    dout.close()
    pd_sck.close()
